package com.tcu.base.security;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.tcu.base.security.anno.NeedTokenVerify;
import com.tcu.base.utils.JwtUtil;
import com.tcu.exception.SmartException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 不是 controller里的接口方法，直接放行
         */
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        /**
         * 是controller里的接口方法
         */
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        /**
         * 如果 接口方法上添加了某种特定注解，要进行处理
         */
        if (method.isAnnotationPresent(NeedTokenVerify.class)) {
            String token = request.getHeader("token");
            if(!StringUtils.hasLength(token)){
                throw new SmartException(20001,"Token为空，请重新登陆");
            }
            boolean verify = false;
            try {
//                进行token的验证
                verify = JwtUtil.verify(token);
            } catch (SignatureVerificationException e) {
                e.printStackTrace();
                throw new SmartException(20001,"无效签名！");
            } catch (TokenExpiredException e){
                throw new SmartException(20001,"token过期！");
            } catch (AlgorithmMismatchException e){
                throw new SmartException(20001,"token算法不一致！");
            } catch (Exception e){
                throw new SmartException(20001,"token失效！");
            }
            return verify;
        }
        /**
         * 如果没有特定注解，直接放行
         */
        return true;

    }
}
